/**
 * 音频管理模块
 * 提供录音功能和音频文件处理
 */

const logger = require('../logger');

// 录音配置
const DEFAULT_CONFIG = {
    duration: 15000, // 默认最长录音时长: 15秒
    sampleRate: 16000, // 采样率
    numberOfChannels: 1, // 声道数
    format: 'mp3', // 音频格式
    frameSize: 2 // 采样帧大小
};

// 录音状态
const RecordingState = {
    IDLE: 'idle',
    RECORDING: 'recording',
    PROCESSING: 'processing',
    ERROR: 'error'
};

// 录音管理器类
class RecorderManager {
    constructor(config = {}) {
        this.config = { ...DEFAULT_CONFIG, ...config };
        this.state = RecordingState.IDLE;
        this.startTime = 0;
        this.audioData = null;
        this.audioDuration = 0;
        this.recorderContext = null;
        this.callbacks = {
            onStart: null,
            onStop: null,
            onError: null,
            onProgress: null,
            onComplete: null
        };

        logger.debug('初始化录音管理器', this.config);
    }

    /**
     * 设置回调函数
     * @param {Object} callbacks 回调函数对象
     */
    setCallbacks(callbacks = {}) {
        if (typeof callbacks !== 'object') {
            logger.warn('设置回调失败: 参数类型错误');
            return;
        }

        this.callbacks = {
            ...this.callbacks,
            ...callbacks
        };

        logger.debug('设置录音回调成功');
    }

    /**
     * 开始录音
     * @param {Object} options 录音选项，可覆盖默认配置
     * @returns {boolean} 是否成功开始录音
     */
    start(options = {}) {
        if (this.state === RecordingState.RECORDING) {
            logger.warn('录音已在进行中');
            return false;
        }

        try {
            // 合并配置
            const currentConfig = { ...this.config, ...options };

            // 初始化录音状态
            this.state = RecordingState.RECORDING;
            this.startTime = Date.now();
            this.audioData = [];
            this.audioDuration = 0;

            logger.info('开始录音', {
                maxDuration: currentConfig.duration,
                sampleRate: currentConfig.sampleRate
            });

            // 模拟开始录音，实际项目中应使用真实的录音API
            // 如在微信小程序中使用 wx.getRecorderManager()
            this.recorderContext = {
                startTime: this.startTime,
                timeoutId: setTimeout(() => {
                    // 达到最大录音时长时自动停止
                    if (this.state === RecordingState.RECORDING) {
                        logger.info('已达到最大录音时长，自动停止');
                        this.stop();
                    }
                }, currentConfig.duration)
            };

            // 触发开始回调
            if (typeof this.callbacks.onStart === 'function') {
                this.callbacks.onStart();
            }

            // 模拟录音进度回调
            this._startProgressSimulation();

            return true;
        } catch (error) {
            this.state = RecordingState.ERROR;
            logger.error('开始录音失败', error);

            // 触发错误回调
            if (typeof this.callbacks.onError === 'function') {
                this.callbacks.onError({
                    errMsg: error.message || '开始录音失败',
                    errCode: -1
                });
            }

            return false;
        }
    }

    /**
     * 停止录音
     * @returns {boolean} 是否成功停止录音
     */
    stop() {
        if (this.state !== RecordingState.RECORDING) {
            logger.warn('没有正在进行的录音');
            return false;
        }

        try {
            // 更新状态
            this.state = RecordingState.PROCESSING;

            // 计算录音时长
            this.audioDuration = Date.now() - this.startTime;

            // 清除自动停止的定时器
            if (this.recorderContext && this.recorderContext.timeoutId) {
                clearTimeout(this.recorderContext.timeoutId);
            }

            // 清除进度模拟的定时器
            if (this.progressTimerId) {
                clearInterval(this.progressTimerId);
            }

            logger.info('停止录音', {
                duration: this.audioDuration
            });

            // 模拟录音数据处理
            // 实际项目中，这里应该处理真实的录音数据
            setTimeout(() => {
                // 模拟生成Base64编码的音频数据
                const mockAudioBase64 = this._generateMockAudioBase64(this.audioDuration);

                // 处理完成
                this.audioData = mockAudioBase64;
                this.state = RecordingState.IDLE;

                logger.info('录音处理完成', {
                    dataSize: this.audioData.length
                });

                // 触发完成回调
                if (typeof this.callbacks.onComplete === 'function') {
                    this.callbacks.onComplete({
                        duration: this.audioDuration,
                        fileSize: this.audioData.length,
                        tempFilePath: `audio_${Date.now()}.mp3`,
                        audioBase64: this.audioData
                    });
                }

                // 触发停止回调
                if (typeof this.callbacks.onStop === 'function') {
                    this.callbacks.onStop({
                        duration: this.audioDuration,
                        fileSize: this.audioData.length
                    });
                }
            }, 300); // 模拟处理延迟

            return true;
        } catch (error) {
            this.state = RecordingState.ERROR;
            logger.error('停止录音失败', error);

            // 触发错误回调
            if (typeof this.callbacks.onError === 'function') {
                this.callbacks.onError({
                    errMsg: error.message || '停止录音失败',
                    errCode: -2
                });
            }

            return false;
        }
    }

    /**
     * 获取当前录音状态
     * @returns {string} 当前状态
     */
    getState() {
        return this.state;
    }

    /**
     * 获取已录制的音频数据
     * @returns {Object} 音频数据对象
     */
    getAudioData() {
        if (!this.audioData) {
            return null;
        }

        return {
            duration: this.audioDuration,
            fileSize: this.audioData.length,
            audioBase64: this.audioData
        };
    }

    /**
     * 清除录音数据
     */
    clear() {
        this.audioData = null;
        this.audioDuration = 0;
        logger.debug('清除录音数据');
    }

    /**
     * 模拟录音进度回调
     * @private
     */
    _startProgressSimulation() {
        // 每100ms触发一次进度回调
        this.progressTimerId = setInterval(() => {
            if (this.state !== RecordingState.RECORDING) {
                clearInterval(this.progressTimerId);
                return;
            }

            const currentDuration = Date.now() - this.startTime;
            const progress = Math.min(currentDuration / this.config.duration, 1);

            // 触发进度回调
            if (typeof this.callbacks.onProgress === 'function') {
                this.callbacks.onProgress({
                    duration: currentDuration,
                    progress: progress
                });
            }
        }, 100);
    }

    /**
     * 生成模拟的音频Base64数据
     * @param {number} duration 音频时长(ms)
     * @returns {string} Base64编码的音频数据
     * @private
     */
    _generateMockAudioBase64(duration) {
        // 实际项目中这里会处理真实的音频数据
        // 这里仅模拟生成随机数据
        const dataLength = Math.round(duration * 0.5); // 模拟大小
        const randomBytes = Array.from(
            { length: dataLength },
            () => Math.floor(Math.random() * 256)
        );

        // 将随机字节转换为Base64字符串
        const base64Chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
        let base64 = '';

        for (let i = 0; i < randomBytes.length; i += 3) {
            const byte1 = randomBytes[i] || 0;
            const byte2 = randomBytes[i + 1] || 0;
            const byte3 = randomBytes[i + 2] || 0;

            const char1 = base64Chars[byte1 >> 2];
            const char2 = base64Chars[((byte1 & 3) << 4) | (byte2 >> 4)];
            const char3 = base64Chars[((byte2 & 15) << 2) | (byte3 >> 6)];
            const char4 = base64Chars[byte3 & 63];

            base64 += char1 + char2 + char3 + char4;
        }

        return base64;
    }
}

// 创建默认录音管理器实例
const defaultRecorderManager = new RecorderManager();

module.exports = {
    RecorderManager,
    defaultRecorderManager,
    RecordingState
}; 